#include "socket.h"
#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>
#include "../config/config.h"
#include "../motion/motion.h"
#include "../buzzer/buzzer.h"

Motion motionSocket;
Buzzer buzzerSocket;

Socket::Socket() {
  Server = new WebSocketsServer(WebSocketsPort);
}

void Socket::init () {
  // 启动WebSocket服务器
  Server->begin();
  // 指定事件处理函数
  Server->onEvent([&](uint8_t num, WStype_t type, uint8_t *payload, size_t length) {
    switch (type)
    {
    case WStype_CONNECTED:
      Serial.println("New connection!");
      break;
    case WStype_DISCONNECTED:
      Serial.println("Close the connection.");
      break;
    case WStype_TEXT:
      String data = (char *)payload;
      Serial.print("data ====== ");
      Serial.println(data);

      // digitalWrite(LED_BUILTIN, HIGH);
      
      String type = getValue(data, '|', 0);
      // 如果是红色摇杆
      if (type == "y")
      {

        // 获取前进或是后退的方向
        String direction = getValue(data, '|', 1);

        Serial.println("direction ====== ");
        Serial.print(direction);
        // 获取前进或是后退的速度
        String speed = getValue(data, '|', 2);
        // 设置运动的速度
        motionSocket.speed(speed.toInt());
        // 设置前进的方向
        motionSocket.run(direction.toInt());
        // 如果是蓝色摇杆
      }
      else if (type == "x")
      {
        // 获取摇杆的左右方向
        String level = getValue(data, '|', 1);
        // 为0 表示松开摇杆，车轮恢复直行
        if (!level.compareTo("0"))
        {
          motionSocket.run(5);
        }
        else
        {
          // 转向
          motionSocket.run(level.toInt());
        }
      }
      // 如果web前端的按钮操作
      else if (type == "b")
      {
        String bType = getValue(data, '|', 1);
        // 打开蜂鸣器
        if (bType == "buzzer") {
          buzzerSocket.warning();

        // 开始自动避障  
        } else if (bType == "obstacle") {
          String va = getValue(data, '|', 2);
          SendClient(String("client|Automatic|")+String(va), IPAddress(192, 168, 4, 2));
        
        } else if (bType == "fronLamp") {
          String status = getValue(data, '|', 2);
          SendClient(String("client|fronLamp|")+String(status), IPAddress(192, 168, 4, 2));
        
        } else if (bType == "doubleFlash") {
          String flash = getValue(data, '|', 2);
          flash == "1" ? motionSocket.open() : motionSocket.close();
          SendClient(String("client|doubleFlash|")+String(flash), IPAddress(192, 168, 4, 2));
        } else if (bType == "openHand") {
          String hand = getValue(data, '|', 2);
          SendClient(String("client|AutoHand|")+String(hand), IPAddress(192, 168, 4, 2));
        }
        
      // 如果是各种传感器  
      } else if (type == "sensor") {
        // 获取是哪一类传感器
        String sensorType = getValue(data, '|', 1);

        // 超声波传感器
        if (sensorType == "ultrasonic") {
          String actionType = getValue(data, '|', 2);
          
          if (actionType == "stop") {
            digitalWrite(LED_BUILTIN, HIGH);
            motionSocket.run(0);
            // 通知前端，自动停车后复位现在用户的拖动状态
            // SendClient(String("server|y|reset"), IPAddress(192, 168, 4, 3));
          } else {
            digitalWrite(LED_BUILTIN, LOW);
          }

        // 控制舵机转动 
        } else if (sensorType == "servo") {
          String pos = getValue(data, '|', 2);
          motionSocket.turn(pos.toInt());

        // 转弯并前进  
        } else if (sensorType == "motor") {

          String turnDirection = getValue(data, '|', 2);
          if (turnDirection == "left") {
            motionSocket.left();
          } else if (turnDirection == "right") {
            motionSocket.right();
          } else if (turnDirection == "straight") {
            motionSocket.straight();
          } else if (turnDirection == "back") {
            motionSocket.backOff();
          }
        } else {
          digitalWrite(LED_BUILTIN, LOW);
        }
      }
     
      break;
    }
  });

}

String Socket::getValue(String data, char separator, int index) {
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length() - 1;

  for (int i = 0; i <= maxIndex && found <= index; i++)
  {
    if (data.charAt(i) == separator || i == maxIndex)
    {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }
  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

//通过IP地址获取客户端编号
int8_t Socket::GetIp(IPAddress ip_needed) {
  for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
    IPAddress ip = Server->remoteIP(i);
    if(ip == ip_needed) {
      // ip found
      return i;
    }
  }
  return -1;
}

// 向指定ip的设备发送消息
void Socket::SendClient(String data, IPAddress ip) {
  Server->sendTXT(GetIp(ip), data);
}